package com.test.clients.service.impl;

import java.util.ArrayList;
import java.util.Collection;

import org.apache.log4j.Logger;

import com.test.clients.dao.ClientsDao;
import com.test.clients.dto.Client;
import com.test.clients.service.ClientsService;
import com.test.dao.DBOperationResult;
import com.test.dao.SearchCriteria;
import com.test.dao.SearchResultSet;
import com.test.utils.search.SearchUtils;
import com.test.utils.search.SearchUtils.SearchResultIndex;

public class ClientsServiceImpl implements ClientsService {

	private ClientsDao clientsDao;

	private Logger logger;

	public boolean addClient(final Client client) {

		logger.debug("START addClient");

		// TODO: add validation
		final DBOperationResult op = clientsDao.add(client);

		logger.debug("DBOperationResult: " + op.name());
		logger.debug("END addClient");

		return op == DBOperationResult.SUCCESS_SINGLE_LINE_OPERATION;
	}

	public boolean updateClient(final Client client) {

		logger.debug("START updateClient");

		// TODO: add validation
		final DBOperationResult op = clientsDao.update(client);

		logger.debug("DBOperationResult: " + op.name());
		logger.debug("END updateClient");

		return op == DBOperationResult.SUCCESS_SINGLE_LINE_OPERATION;
	}

	public boolean removeClient(final Client client) {

		logger.debug("START removeClient");

		// TODO: add validation
		final DBOperationResult op = clientsDao.remove(client);

		logger.debug("DBOperationResult: " + op.name());
		logger.debug("END removeClient");

		return op == DBOperationResult.SUCCESS_SINGLE_LINE_OPERATION;
	}

	public Client getClientById(final int clientId) {

		logger.debug("START getClientById");
		logger.debug("clientId: " + clientId);

		final Client client = clientsDao.load(clientId);

		logger.debug("END getClientById");

		return client;
	}

	public SearchResultSet<Client> searchForClients(final SearchCriteria criteria) {

		logger.debug("START searchForClients");

		// TODO: validate criteria
		final SearchResultSet<Client> result = new SearchResultSet<Client>();
		final Collection<Client> fullResultList = clientsDao.search(criteria.getProperties());

		if (fullResultList == null) {
			result.setOpResult(DBOperationResult.ERROR_UNKNOWN);
			result.setResultList(null);
			result.setTotalResultSize(0);
		} else if (fullResultList.size() == 0) {
			result.setOpResult(DBOperationResult.ERROR_NOT_FOUND);
			result.setResultList(fullResultList);
			result.setTotalResultSize(0);
		} else {
			final SearchResultIndex indexes = SearchUtils.calculateIndexes(fullResultList.size(),
					criteria.getPageNumber(), criteria.getItemsPerPage());
			result.setTotalResultSize(fullResultList.size());
			result.setOpResult(fullResultList.size() > 1 ? DBOperationResult.SUCCESS_MULTIPLE_LINES_OPERATION : DBOperationResult.SUCCESS_SINGLE_LINE_OPERATION);
			if (indexes.getStartIndex() == -1) {
				result.setResultList(new ArrayList<Client>());
			} else {
				result.setResultList(new ArrayList<Client>(fullResultList).subList(indexes.getStartIndex(), indexes.getEndIndex()));				
			}
		}

		// TODO Auto-generated method stub

		logger.debug("END searchForClients");

		return result;
	}

	public ClientsDao getClientsDao() {
		return clientsDao;
	}

	public void setClientsDao(ClientsDao clientsDao) {
		this.clientsDao = clientsDao;
	}

	public Logger getLogger() {
		return logger;
	}

	public void setLogger(Logger logger) {
		this.logger = logger;
	}

}
